OKhttp的缓存是通过CacheInterceptor这个拦截器实现的,它的实现如下:
1 | public final class CacheInterceptor implements Interceptor { |
CacheInterceptor内部持有一个InternalCache,它负责缓存的存取,而CacheStrategy用来控制缓存的存取,决定什么时候用缓存,什么时候使用网络进行请求。它是通过其内部的networkRequest和cacheResponse决定的,当networkRequest的值为null表示缓存有效不进行网络请求,而当cacheResponse为null是表示缓存失效或者未命中,需要进行网络请求。当它们都不为null,则根据响应结果来判断缓存是否失效。
CacehStrategy通过Request和候选的缓存进行构造的,我们看看它的内部是如何实现的
CacheStrategy strategy = new CacheStrategy.Factory(now, chain.request(), cacheCandidate).get();
1 | public final class CacheStrategy { |
在getCandidate方法中实现了构造CacheStrategy实例的逻辑,总的来说:
一 使用网络进行请求的包括,即networkRequest != null :
- 缓存未命中
- https请求缺少handshake信息
- request指定的CacheControl不进行缓存
- 缓存的Response头部没有缓存相关的信息如ETag,If-None-Match,If-Modified-Since等
二 使用缓存请求的情况,即cacheResponse != null
- 缓存有效,未超过其失效时间
三 networkRequest != null 且 cacheResponse != null
- 缓存是否有效,要根据响应结果来判断
缓存的写入
在CacheInterceptor内部它对Response进行缓存的实现如下:
1 | if (cache != null) { |
写入缓存是在Cache类中实现的,它内部持有一个internalCache,它正是CacheInterceptor拦截器内部的缓存引用。这里我们先看cache put方法的实现
1 | CacheRequest put(Response response) { |
关于DiskLruCache将在另外的篇章中介绍。